package com.hyg.module_third_party_demo.activity;


import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.alibaba.android.arouter.facade.annotation.Route;
import com.hyg.lib_common.Base.BaseActivity;
import com.hyg.lib_common.constant.Constants;
import com.hyg.module_third_party_demo.R;
import com.hyg.module_third_party_demo.entity.FastJsonTest;
import com.hyg.module_third_party_demo.entity.User;
import com.hyg.module_third_party_demo.rxbus.RxBus;
import com.jakewharton.rxbinding2.view.RxView;
import com.jakewharton.rxbinding2.widget.RxTextView;

import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import retrofit2.http.GET;
import retrofit2.http.Query;

// 参考  https://gank.io/post/560e15be2dca930e00da1083
@SuppressLint("CheckResult")
@Route(path = Constants.PATH_ACTIVITY_MODULE_DEMO_RXANDROID)
public class RxAndroidActivity extends BaseActivity {
    Observer<Integer> observer;
    Disposable disposable;
    Button testBtn;
    int number = 123;

    protected ArrayList<Subscription> rxBusList = new ArrayList<>();

    @GET("/user")
    public Observable<User> getUser(@Query("userId") String userId) {
        return null;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rx_android);
        init();
    }

    public void init() {
        testBtn = findViewById(R.id.btn_test);
        observer = new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {
                disposable = d;
            }

            @Override
            public void onNext(Integer integer) {
//                if (integer == 2) {
//                    disposable.dispose();   //不再接受上游事件
//                    Log.i(TAG, "onNext: disposable.dispose()");
//                }
            }

            @Override
            public void onError(Throwable t) {

            }

            @Override
            public void onComplete() {

            }
        };
        subscribe();
    }

    /**
     * description: 标准模式
     *
     * @author visitant
     * @time 2020/11/18 16:22
     */
    public void onCommonClicked(View view) {
//        Observable observable = Observable.just("Hello", "Hi", "Aloha");
        // 将会依次调用：onNext("Hello");onNext("Hi");onNext("Aloha");onCompleted();
        //from(T[]) / from(Iterable<? extends T>) : 将传入的数组或 Iterable 拆分成具体对象后，依次发送出来。
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                e.onNext(1);
                e.onNext(2);
                e.onNext(3);
            }
        })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                //Schedulers.immediate(): 直接在当前线程运行，相当于不指定线程。这是默认的 Scheduler。
                //Schedulers.newThread(): 总是启用新线程，并在新线程执行操作。
                //Schedulers.io(): I/O 操作（读写文件、读写数据库、网络信息交互等）所使用的 Scheduler。行为模式和 newThread() 差不多，区别在于 io() 的内部实现是是用一个无数量上限的线程池，可以重用空闲的线程，因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中，可以避免创建不必要的线程。
                //Schedulers.computation(): 计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算，即不会被 I/O 等操作限制性能的操作，例如图形的计算。这个 Scheduler 使用的固定的线程池，大小为 CPU 核数。不要把 I/O 操作放在 computation() 中，否则 I/O 操作的等待时间会浪费 CPU。
                //另外， Android 还有一个专用的 AndroidSchedulers.mainThread()，它指定的操作将在 Android 主线程运行。
                .subscribe(observer);
//              .subscribe(new Consumer<Integer>() {                        //缺省写法
//                    @Override
//                    public void accept(Integer integer) throws Exception {
//
//                    }
//                });

//        new Consumer<T>() {                                               //onNext
//            @Override
//            public void accept(T o) throws Exception {
//
//            }
//        };
//        new Consumer<Throwable>() {                                       //onError
//            @Override
//            public void accept(Throwable throwable)
//                    throws Exception {
//
//            }
//        };
//        new Action() {                                                    //onComplete
//            @Override
//            public void run() throws Exception {
//
//            }
//        };
    }


    /**
     * description: map变换
     *
     * @author visitant
     * @time 2020/11/18 16:21
     */
    public void onMapTransformation(View view) {
        Observable.just("testString") // 输入类型 String
                .map(new Function<String, Integer>() {
                    @Override
                    public Integer apply(String s) throws Exception {
                        return 200;
                    }
                })
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                    }
                });
    }


    /**
     * description: FlatMap变换
     *
     * @author visitant
     * @time 2020/11/18 16:21
     */
    public void onFlatMapTransformation(View view) {
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<Integer> e) throws Exception {
                e.onNext(1);
                e.onNext(2);
                e.onNext(3);
            }
        }).flatMap(new Function<Integer, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(@NonNull Integer integer) throws Exception {
                List<String> list = new ArrayList<>();
                for (int i = 0; i < 4; i++) {
                    list.add(integer + " I am value " + i);
                }
                return Observable.fromIterable(list);
//                        .delay(delayTime, TimeUnit.MILLISECONDS);
            }
        })
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String s) throws Exception {
                    }
                });
    }

    /**
     * description: 配合Retrofit使用
     *
     * @author visitant
     * @time 2020/11/18 16:20
     */
    public void withRetrofit(View view) {
        getUser("123")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<User>() {
                    @Override
                    public void accept(User user) throws Exception {
                    }
                });
    }


    /**
     * description: 配合RxBinding使用
     *
     * @author visitant
     * @time 2020/11/18 16:21
     */
    public void withRxBinding(View view) {
        RxView.clicks(testBtn)
//        .longClicks(testBtn)          //长按
                .throttleFirst(5, TimeUnit.SECONDS)     //防止5秒内多次触碰
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        number = number * 2;
                        testBtn.setText(number + "");
                    }
                });

    }

    /**
     * description: 发送事间
     *
     * @author visitant
     * @time 2020/11/19 13:35
     */
    public void withEventBus(View view) {
        RxBus.getInstance().send(new User("testName", 66, true));
    }

    /**
     * description:  发布订阅
     *
     * @author visitant
     * @time 2020/11/19 13:35
     */
    public void subscribe() {
        RxBus.getInstance().subscribe(User.class, new Consumer<User>() {
            @Override
            public void accept(User user) throws Exception {
            }
        });
    }

    @Override
    public void finish() {
        super.finish();
        RxBus.getInstance().unSubcribe();
    }


}
